﻿using SQLDeploy.Data.Connections;
using SQLDeploy.Data.Deployment.Steps.Tasks;
using SQLDeploy.Execution.Deployment.Steps.Tasks;
using SQLDeploy.Utils;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;


namespace SQLDeploy.Execution.Internal
{
    internal abstract class Common
    {
        private Common() { }

        public static bool PerformCommonTaskExectorValidation(ITaskExecutor task, Data.Environments.Environment executionEnvironment)
        {
            Check.notNull(task, "task");
            Check.notNull(executionEnvironment, "executionEnvironment");

            bool retVal = true;
            try
            {
                //First perform TaskInternal Validation, I.E. check that files exist
                if (!task.IsValidating)
                    task.Begin_Revalidate();
                while (task.IsValidating)
                    Thread.Sleep(500);
                if (!task.IsValid)
                {
                    Trace.TraceError("{0}Failed to validate Task, see prior message(s) for more details.", task.TaskNameHeader);
                    return false;
                }

                //If Task is replicated only and not in replicated Environment return true;
                if (task.ReplicatedOnly && !executionEnvironment.IsReplicated)
                {
                    Trace.TraceInformation("{0}Validation of this task is being skipped since it is marked for only to execute in Replicated Environments, and Environment [{1}] is not replicated.",
                        task.TaskNameHeader, executionEnvironment.Name);
                    return true;
                }

                //Make sure there is at least one connection to process the task
                List<_BaseConnection> connections = task.getConnection();
                if (connections == null || connections.Count == 0)
                {
                    Trace.TraceError("{0}Connection {1} does not exist in {2} Environment.",
                        task.TaskNameHeader, task.ConnectionName, executionEnvironment.Name);
                    return false;
                }

                //Validate permissions on each connection.
                foreach (_BaseConnection connection in connections)
                {
                    if(!connection.GetType().Equals(task.RequiredConnectionType()))
                    {
                        Trace.TraceError("{0}{1} expected connection type of {2}, and found connection type of {3}.",
                            task.TaskNameHeader, task.GetType().Name,
                            task.RequiredConnectionType().Name, connection.GetType().Name);
                        return false;
                    }

                    //Revalidate the underlying connection
                    if (!connection.IsValidating)
                        connection.Begin_Revalidate();
                    while (connection.IsValidating)
                        Thread.Sleep(1000);
                    if (!connection.IsValid)
                    {
                        Trace.TraceError("{0}Failed to validate the tasks connection [{1}].",
                            task.TaskNameHeader, task.ConnectionName);
                        return false;
                    }
                }
            }
            catch (Exception e)
            {
                Trace.TraceError("{0}PerformCommonTaskExectorValidation - Exception occured:{1}.",
                    task.TaskNameHeader, e.ToString());
                retVal = false;
            }
            //If we've reached here take the retval cause it's probably and error
            return retVal;
        }

       
    }
}
